package cn.codeartist.springboot.component.util;

import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;

/**
 * 校验工具类
 *
 * @author 艾江南
 * @date 2019/4/22
 */
public final class ValidatorUtils {

    public static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 校验方法
     */
    public static <T> void validate(T t, Class<?>... groups) {
        Set<ConstraintViolation<T>> validate = VALIDATOR.validate(t, groups);
        if (!CollectionUtils.isEmpty(validate)) {
            throw new ConstraintViolationException(validate);
        }
    }

    /**
     * 校验方法
     */
    public static <T> String validateMessage(T t, Class<?>... groups) {
        Set<ConstraintViolation<T>> validate = VALIDATOR.validate(t, groups);
        if (!CollectionUtils.isEmpty(validate)) {
            return validate.iterator().next().getMessage();
        }
        return null;
    }

    /**
     * 校验方法
     */
    public static <T> boolean validateResult(T t, Class<?>... groups) {
        return !CollectionUtils.isEmpty(VALIDATOR.validate(t, groups));
    }

    /**
     * 从校验异常里面获取消息
     */
    public static String parseMessage(Exception e) {
        if (e instanceof ConstraintViolationException) {
            ConstraintViolationException exception = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> violationSet = exception.getConstraintViolations();
            ConstraintViolation<?> violation = violationSet.iterator().next();
            return violation.getMessage();
        }
        if (e instanceof BindException) {
            BindException exception = (BindException) e;
            List<ObjectError> errors = exception.getBindingResult().getAllErrors();
            return errors.get(0).getDefaultMessage();
        }
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            List<ObjectError> errors = exception.getBindingResult().getAllErrors();
            return errors.get(0).getDefaultMessage();
        }
        return null;
    }
}
